home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software <no-Inc> */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / No-Cost<no-tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello */
- /* */
- /* */
- /* GENERAL PURPOSE FILE RECEPTION (Xmodem/YModem/Sealink) */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.210. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT THE AUTHORS */
- /* AT THE ADDRESSES LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO */
- /* USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE */
- /* BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU */
- /* ARE ABLE TO REACH WITH THE AUTHORS. */
- /* */
- /* */
- /* The Authors can be reached at the following addresses: */
- /* */
- /* Robert C. Hartman Vincent E. Perriello */
- /* Spark Software VEP Software */
- /* 427-3 Amherst Street 111 Carroll Street */
- /* CS2032, Suite 232 Naugatuck, CT 06770 */
- /* Nashua, NH 03061 */
- /* */
- /* FidoNet 1:132/101 FidoNet 1:141/491 */
- /* Data (603) 888-8179 Data (203) 729-7569 */
- /* */
- /* Please feel free to contact us at any time to share your comments */
- /* about our software and/or licensing policies. */
- /* */
- /* */
- /* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
- /* The original work is (C) Copyright 1987, Wynn Wagner III. The original */
- /* author has graciously allowed us to use his code in this work. */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <sys/types.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <time.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
- #include <io.h>
-
- #ifdef __TURBOC__
- #include "tc_utime.h"
- #include <alloc.h>
- #else
- #include <sys/utime.h>
- #include <malloc.h>
- #endif
-
- #include "com.h"
- #include "xfer.h"
- #include "zmodem.h"
- #include "keybd.h"
- #include "sbuf.h"
- #include "sched.h"
- #include "externs.h"
- #include "prototyp.h"
- #include "find.h" /*PLF Fri 05-05-1989 23:35:56 */
-
- static void SendACK (void);
- static void SendNAK (void);
- static void getblock (void);
-
- /*--------------------------------------------------------------------------*/
- /* LOCALS */
- /*--------------------------------------------------------------------------*/
- static long block_number;
- static long base_block;
- static char *stat_msg;
- static int sliding;
- static int block_size;
- static int do_chksum;
- static int errs;
- static int real_errs;
- static long fsize1;
- static int fsize2;
- static char *buffer;
- static FILE *infile;
- static char *_fpath;
- static struct zero_block *header;
- static char final_name[80];
- static int first_block; /* 1 = first block/Matrix
- * packet */
-
- static char *receiving = "Receiving ";
- static int may_be_seadog;
- static int netmail;
- static int recv_ackless;
- static int did_nak;
- static long filesecs;
-
- #define two_s "%s%s"
-
-
-
- /*--------------------------------------------------------------------------*/
- /* SEND ACK */
- /*--------------------------------------------------------------------------*/
- static void SendACK ()
- {
- if ((!recv_ackless) || (block_number == 0))
- {
- SENDBYTE (ACK);
- if (sliding)
- {
- SENDBYTE ((unsigned char) block_number);
- SENDBYTE ((unsigned char) (~(block_number)));
- }
-
- if (block_number <= fsize1)
- {
- /* No-nonsense status line. Don't waste time with frills... */
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
- }
- }
- }
-
- else if (((!(block_number & 0x001F)) && (block_number < fsize1))
- || (block_number == fsize1))
- {
- /* In Overdrive only put out last block and n/32 */
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
- sb_putc (filewin, '*');
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
- /*PLF bdos (9, (unsigned int) "*$", 0); */
- putch('*'); /*PLF Fri 05-05-1989 06:58:31 */
- }
- }
-
- errs = 0;
- } /* SendACK */
-
-
-
- /*--------------------------------------------------------------------------*/
- /* SEND NAK */
- /*--------------------------------------------------------------------------*/
- static void SendNAK ()
- {
- int i;
- long t1;
-
- errs++;
- real_errs++;
- if (errs > 6)
- {
- stat_msg = FUBAR_msg;
- return;
- }
-
- if (++did_nak > 8)
- {
- recv_ackless = 0;
- }
-
- CLEAR_INBOUND ();
-
- /*--------------------------------------------------------------------*/
- /* Let the connection cool its heels. */
- /*--------------------------------------------------------------------*/
- if (!recv_ackless)
- {
- /* Set a timer for waiting */
- t1 = timerset (3000);
- if ((base_block != block_number) || (errs > 1))
- do
- {
- i = TIMED_READ (1);
- if (!CARRIER)
- return;
- if (timeup (t1))
- break;
- }
- while (i >= 0);
- }
-
- if (block_number > base_block)
- SENDBYTE (NAK);
- else
- {
- if ((errs < 5) && (!do_chksum))
- SENDBYTE ('C');
- else
- {
- do_chksum = 1;
- SENDBYTE (NAK);
- }
- }
-
- if (sliding)
- {
- SENDBYTE ((unsigned char) block_number);
- SENDBYTE ((unsigned char) (~(block_number)));
- }
-
- if (block_number <= fsize1)
- {
- /* No time for anything but the bare essentials... */
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 2);
- sb_puts (filewin, ultoa (((unsigned long) (block_number)), e_input, 10));
- sb_show ();
- }
- else
- {
- gotoxy (locate_x, locate_y);
- cputs (ultoa (((unsigned long) (block_number)), e_input, 10));
- }
- }
- } /* SendNAK */
-
- /*--------------------------------------------------------------------------*/
- /* GET BLOCK */
- /*--------------------------------------------------------------------------*/
- static void getblock ()
- {
- register int i;
- register char *sptr;
-
- char *p;
- unsigned int crc;
- int in_char;
- int is_resend;
- int blockerr;
- unsigned char chksum;
- char junkbuff[128];
-
- blockerr = is_resend = 0;
- chksum = '\0';
-
-
- /*--------------------------------------------------------------------*/
- /* HEADER: Block number */
- /*--------------------------------------------------------------------*/
- in_char = TIMED_READ (5);
- if (in_char != ((int)(block_number) & 0xff))
- {
- if (in_char < (int)block_number)
- is_resend = 1;
- else if ((block_number) || (in_char != 1))
- {
- blockerr++;
- stat_msg = SYNC_msg;
- }
- else block_number = 1;
- }
-
- /*--------------------------------------------------------------------*/
- /* HEADER: Complement of the block number */
- /*--------------------------------------------------------------------*/
- i = TIMED_READ (5);
- if ((i & 0xff) != ((~in_char) & 0xff))
- {
- blockerr++;
- stat_msg = CMPL_msg;
- }
-
- /*--------------------------------------------------------------------*/
- /* DATA */
- /*--------------------------------------------------------------------*/
- for (sptr = buffer, i = 0; i < block_size; i++, sptr++)
- {
- in_char = TIMED_READ (5);
- if (in_char < 0) /* We get EOF for timeout or
- * carrier */
- {
- if (CARRIER) /* If we have carrier it was
- * timeout */
- {
- SendNAK ();
- stat_msg = TIME_msg;
- }
- return; /* return in either case */
- }
- sptr[0] = (char) in_char;
- }
-
- /*--------------------------------------------------------------------*/
- /* CHECK */
- /*--------------------------------------------------------------------*/
- if (do_chksum)
- {
- for (sptr = buffer, i = 0; i < block_size; i++, sptr++)
- chksum += sptr[0];
-
- if (TIMED_READ (5) != chksum)
- {
- stat_msg = CHK_msg;
- blockerr++;
- }
- }
- else
- {
- unsigned int lsb, msb;
-
- for (sptr = buffer, i = crc = 0; i < block_size; i++, sptr++)
- crc = xcrc (crc, (byte) sptr[0]);
-
- msb = TIMED_READ (3);
- lsb = TIMED_READ (3);
- if ((lsb < 0) || (msb < 0))
- {
- stat_msg = SHRT_msg;
- if (!block_number)
- sliding = 0;
- blockerr++;
- }
- else if (((msb << 8) | lsb) != crc)
- {
- stat_msg = CRC_msg;
- blockerr++;
- }
- }
-
- if (blockerr)
- SendNAK ();
- else
- {
- SendACK ();
- if (is_resend)
- return;
-
- if (block_number)
- {
- if (block_number < fsize1)
- fwrite (buffer, block_size, 1, infile);
- else if (block_number == fsize1)
- fwrite (buffer, fsize2, 1, infile);
-
- if (first_block)
- {
- struct _pkthdr *packet;
-
- packet = (struct _pkthdr *) buffer;
- if (!remote_capabilities)
- {
- remote_net = packet->orig_net;
- remote_node = packet->orig_node;
- remote_zone = packet->orig_zone;
- }
- first_block = 0;
- if (who_is_he)
- {
- if (nodefind (remote_zone, remote_net, remote_node, 1))
- {
- if (!remote_zone)
- remote_zone = found_zone;
-
- sprintf (junkbuff, " Remote System: %s (%u:%u/%u)",
- newnodedes.SystemName,
- remote_zone,
- remote_net,
- remote_node);
- }
- else
- {
- sprintf (junkbuff, " Remote System: UNKNOWN - FSC-0001 Mailer (%u:%u/%u)",
- remote_zone,
- remote_net,
- remote_node);
- }
-
- last_type (2, remote_zone, remote_net, remote_node);
- status_line (junkbuff);
- who_is_he = 0;
- }
- }
- }
- else
- {
- if (!first_block)
- {
- sptr = &(header->name[0]);
- if (netmail)
- invent_pkt_name (sptr);
-
- for (i = 0; ((sptr[i]) && (i < 17)); i++)
- if (sptr[i] <= ' ')
- sptr[i] = '\0';
-
- if (sptr[0])
- {
- sprintf (final_name, two_s, _fpath, sptr);
- sptr = final_name;
- fancy_str (sptr);
-
- i = strlen (final_name) - 1;
-
- if (netmail)
- p = check_netfile (sptr);
- else
- p = receiving;
-
- if (un_attended && fullscreen)
- {
- clear_filetransfer ();
- sb_move (filewin, 1, 2);
- sb_puts (filewin, p);
- sb_puts (filewin, sptr);
- sb_show ();
- }
- else if (locate_y > 1)
- {
- gotoxy (2, locate_y - 1);
- cprintf (p);
- cputs (sptr);
- }
- }
- else
- status_line ("!Grunged hdr");
- }
-
- if (header->size)
- {
- fsize1 = (long) (header->size / 128L);
- if (fsize2 = (int) (header->size % 128))
- ++fsize1;
- else
- fsize2 = 128;
- sprintf (junkbuff, "%s %ld blks", (netmail) ? " " : "", fsize1);
- if (un_attended && fullscreen)
- {
- sb_puts (filewin, junkbuff);
- sb_show ();
- }
- else
- cprintf ("%s", junkbuff);
- }
-
- if (header->time)
- {
- filesecs = header->time;
- }
- else
- {
- filesecs = -1;
- }
-
- if (header->moi[0])
- {
- if (un_attended && fullscreen)
- {
- sprintf (junkbuff, " from %s", header->moi);
- sb_puts (filewin, junkbuff);
- sb_show ();
- }
- else
- cprintf (" from %s", header->moi);
- }
-
- if ((cur_baud >= 9600) && header->noacks && !no_overdrive)
- {
- recv_ackless = 1;
- }
-
- if (!netmail)
- {
- if (!(un_attended && fullscreen))
- {
- set_xy (NULL);
- locate_x += 2;
- }
- }
- }
- block_number++;
- }
- } /* getblock */
-
- /*--------------------------------------------------------------------------*/
- /* GENERAL PURPOSE FILE RECEIPTION ROUTINE */
- /*--------------------------------------------------------------------------*/
- char *
- receive_file (fpath, fname, protocol)
- char *fpath, *fname, protocol;
- {
- char tmpname[80];
- int in_char;
- struct utimbuf times;
- long t1;
-
- did_nak = 0;
- filesecs = -1;
- XON_DISABLE ();
-
- if (protocol == 'F')
- {
- may_be_seadog = 1;
- netmail = 0;
- protocol = 'S';
- first_block = 0;
- }
- else if (protocol == 'B')
- {
- protocol = 'S';
- netmail = 1;
- may_be_seadog = 1;
- first_block = 1;
- }
- else
- {
- may_be_seadog = 0;
- netmail = 0;
- first_block = 0;
- }
-
- CLEAR_IOERR ();
- fsize1 = 65535;
- if (fname)
- for (in_char = 0; fname[in_char]; in_char++)
- if ((fname[in_char] == '*') || (fname[in_char] == '?'))
- fname[0] = '\0';
-
- _fpath = fpath;
- sliding = 1;
- base_block =
- do_chksum =
- errs = 0;
- block_size = 128;
-
- locate_y = wherey ();
- locate_x = 3 + wherex ();
-
- switch (protocol)
- {
- case 'X':
- base_block = 1;
- sliding = 0;
- break;
- case 'Y':
- base_block = 1;
- sliding = 0;
- block_size = 1024;
- break;
- case 'S':
- break;
- case 'T':
- break;
- case 'M':
- base_block = 1;
- sliding = 0;
- break;
- default:
- status_line ("!Protocol??");
- return NULL;
- }
-
- block_number = base_block;
-
- sprintf (tmpname, "%s_TMP_.$$$", fpath);
- sprintf (final_name, two_s, _fpath, (fname && fname[0]) ? fname : "UNKNOWN.$$$");
-
- infile = fopen (tmpname, write_binary);
- if (got_error (CREATE_msg, tmpname))
- return (NULL);
- if (isatty (fileno (infile)))
- {
- errno = 1;
- got_error (DEVICE_msg, tmpname);
- fclose (infile);
- return (NULL);
- }
-
- buffer = Txbuf;
- header = (struct zero_block *) buffer;
- if (!buffer)
- {
- status_line ("!MEM:ulbuf");
- return (NULL);
- }
-
- if (!(un_attended && fullscreen))
- {
- set_xy (NULL);
- locate_x += 2;
- }
- stat_msg = NULL;
- throughput (0, 0L);
-
- /* If we did the SEAdog kludge, then don't send another NAK */
- if (!may_be_seadog)
- SendNAK ();
-
- t1 = timerset (300);
- real_errs = 0;
-
- loop_top:
-
- if (got_ESC ())
- {
- stat_msg = KBD_msg;
- goto fubar;
- }
-
- in_char = TIMED_READ (4);
-
- switch (in_char)
- {
- case SOH:
- /*--------------------------------------------*/
- /* SOH: 128 byte block header */
- /*--------------------------------------------*/
- block_size = 128;
- getblock ();
- t1 = timerset (300);
- break;
-
- case STX:
- /*--------------------------------------------*/
- /* STX: YModem 1k block header */
- /*--------------------------------------------*/
- block_size = 1024;
- getblock ();
- t1 = timerset (300);
- break;
-
- case SYN:
- /*--------------------------------------------*/
- /* SYN: TeLink Zero block header */
- /*--------------------------------------------*/
- do_chksum = 1;
- getblock ();
- do_chksum = 0;
- t1 = timerset (300);
- break;
-
- case CAN:
- /*--------------------------------------------*/
- /* CAN */
- /*--------------------------------------------*/
- if (TIMED_READ (2) == CAN)
- {
- stat_msg = CAN_msg;
- goto fubar;
- }
- t1 = timerset (300);
- break;
-
- case EOT:
- /*--------------------------------------------*/
- /* EOT */
- /*--------------------------------------------*/
- stat_msg = EOT_msg;
- t1 = timerset (20);
- while (!timeup (t1))
- {
- TIMED_READ (0);
- time_release ();
- }
- if (block_number)
- goto done;
- else goto fubar;
-
- default:
- /*--------------------------------------------*/
- /* Default */
- /*--------------------------------------------*/
- if (in_char > 0)
- {
- if (!may_be_seadog)
- {
- if (!(fullscreen && un_attended))
- {
- gotoxy (locate_x, locate_y);
- cprintf ("??? [%Xh, blk %d] ", in_char, block_number);
- set_xy (receiving);
- }
- }
- }
- else if (!CARRIER) /* Was it a timeout or
- * carrier loss? */
- goto lost; /* Carrier, get out of here */
-
- /*
- * Debris is tolerable for up to the amount of time we are willing
- * to wait for a start of a block. Right now it is 10 seconds.
- */
-
- /*
- * If may_be_seadog is set, then we know we should get an SOH pretty
- * soon
- */
- if (timeup (t1) || !may_be_seadog)
- SendNAK ();
- break;
- } /* switch */
-
- if (errs > 14)
- {
- stat_msg = FUBAR_msg;
- goto fubar;
- }
-
- else if (got_error (WRITE_msg, fname))
- {
- stat_msg = IO_msg;
- goto fubar;
- }
-
- if (stat_msg)
- {
- if (fullscreen && un_attended)
- {
- sb_puts (filewin, stat_msg);
- sb_puts (filewin, " ");
- sb_show ();
- }
- else
- {
- cputs (stat_msg);
- cputs (" ");
- }
- stat_msg = NULL;
- }
- goto loop_top;
-
- lost:
-
- stat_msg = CARRIER_msg;
-
- fubar:
-
- if (infile)
- {
- fclose (infile);
- got_error (CLOSE_msg, tmpname);
- unlink (tmpname);
- got_error (UNLINK_msg, tmpname);
- }
-
- CLEAR_OUTBOUND ();
-
- if (stat_msg != EOT_msg)
- {
- for (in_char = 0; in_char < 5; in_char++)
- SENDBYTE (CAN);
-
- status_line ("!File not received: %s", stat_msg);
- }
-
- CLEAR_INBOUND ();
- return NULL;
-
-
- done:
-
- recv_ackless = 0;
- SendACK ();
-
- if (infile)
- {
- int i, j, k;
- FSCAN *dh; /*PLF Fri 05-05-1989 23:30:39 */
-
- fclose (infile);
- got_error (CLOSE_msg, tmpname);
-
- i = strlen (tmpname) - 1;
- j = strlen (final_name) - 1;
-
- if (tmpname[i] == '.')
- tmpname[i] = '\0';
- if (final_name[j] == '.')
- {
- final_name[j] = '\0';
- --j;
- }
-
- i = 0;
- k = is_arcmail (final_name, j);
- if ((!overwrite) || k)
- {
- while (rename (tmpname, final_name))
- {
- if (isdigit (final_name[j]))
- final_name[j]++;
- else final_name[j] = '0';
- if (!isdigit (final_name[j]))
- return (tmpname);
- i = 1;
- }
- CLEAR_IOERR ();
- }
- else
- {
- unlink (final_name);
- rename (tmpname, final_name);
- }
- if (i)
- {
- if (locate_y && !(fullscreen && un_attended))
- gotoxy (2, locate_y - 1);
- status_line ("+Dupe file renamed: %s", final_name);
- }
-
- if (filesecs != -1)
- {
- tzset ();
- times.modtime = filesecs + timezone;
- times.actime = filesecs + timezone;
- utime (final_name, ×);
- }
- dh = opendir(); /*PLF Fri 05-05-1989 23:32:06 */
- if (!findfirst(final_name, _A_NORMAL, dh)) /*PLF Fri 05-05-1989 23:32:37 */
- {
- if (!i)
- {
- if (locate_y && !(fullscreen && un_attended))
- gotoxy (2, locate_y - 1);
- }
- if (real_errs > 4)
- status_line ("+Corrected %d errors in %d blocks",
- real_errs, fsize1);
- status_line ("+Received-S %s", final_name);
- throughput (1, dh->size); /*PLF Fri 05-05-1989 23:33:38 */
-
- update_files (0);
-
- dh->size /= 1024L; /*PLF Fri 05-05-1989 23:33:41 */
- strcpy (final_name, dh->name); /*PLF Fri 05-05-1989 23:33:43 */
- closedir(dh); /*PLF Fri 05-05-1989 23:34:18 */
- CLEAR_IOERR ();
- return final_name; /* signal what file we got */
- }
- closedir(dh); /*PLF Fri 05-05-1989 23:34:18 */
- }
- CLEAR_IOERR ();
- return NULL;
-
- }
-
- /* END OF FILE: recv_sl.c */